package CapaLogica;

import CapaDatos.*;
import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JOptionPane;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class ManejoXML
{
    private static final String errorCargando =
            "<html>Error fatal! No se puede cargar la información de ";

    private static String dirReservas      = "C:\\iResort\\Reservaciones\\";
    private static String dirFechas        = "C:\\iResort\\FechasReservadas\\";
    private static String fileCargos       = "C:\\iResort\\cargos.xml";
    private static String fileEmpleados    = "C:\\iResort\\empleados.xml";
    private static String fileRestaurants  = "C:\\iResort\\restaurants.xml";
    private static String fileHabitaciones = "C:\\iResort\\habitaciones.xml";
    private static String fileClientes     = "C:\\iResort\\clientes.xml";

    // <editor-fold defaultstate="collapsed" desc="Para cambiar el diretorio de iResort">
    public static void setCarpeta(String dir) {
        dirReservas      = dir + "\\Reservaciones\\";
        dirFechas        = dir + "\\FechasReservadas\\";
        fileCargos       = dir + "\\cargos.xml";
        fileEmpleados    = dir + "\\empleados.xml";
        fileRestaurants  = dir + "\\restaurants.xml";
        fileHabitaciones = dir + "\\habitaciones.xml";
        fileClientes     = dir + "\\clientes.xml";

        File carpeta = new File(dirReservas);
        if (!carpeta.exists())
            carpeta.mkdir();

        carpeta = new File(dirFechas);
        if (!carpeta.exists())
            carpeta.mkdir();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="public Guardar/Cargar">
    public static void cargarDatos() {
        cargarCargos();
        cargarEmpleados();
        cargarRestaurants();
        cargarHabitaciones();
        cargarClientes();
    }

    public static void guardarDatos() {
        guardarCargos();
        guardarEmpleados();
        guardarRestaurants();
        guardarHabitaciones();
        guardarClientes();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Lectura">
    private static void cargarCargos() {
        Document doc = obtenerArchivo (fileCargos, "los cargos");

        Element lista = doc.getRootElement();
        List habitaciones = lista.getChildren("cargo");
        Iterator i = habitaciones.iterator();

        while (i.hasNext())
        {
            Element e = (Element) i.next();
            String nombre = e.getAttributeValue("nombre");
            String sueldo = e.getAttributeValue("sueldoBase");

            AdministracionInterna.agregarCargo(nombre, sueldo);
        }
    }

    private static void cargarEmpleados() {
        Document doc = obtenerArchivo (fileEmpleados, "los empleados");

        Element lista = doc.getRootElement();
        List empleados = lista.getChildren("empleado");
        Iterator i = empleados.iterator();

        while (i.hasNext())
        {
            Element e = (Element) i.next();
            String nombre             = e.getAttributeValue("nombre");
            String apellido           = e.getAttributeValue("apellido");
            String cedula             = e.getAttributeValue("cedula");
            char sexo                 = e.getAttributeValue("sexo").charAt(0);
            char estadoCivil          = e.getAttributeValue("estadoCivil").charAt(0);
            String fechaNacimiento    = e.getAttributeValue("fechaNacimiento");
            String cargo              = e.getAttributeValue("cargo");
            String puesto             = e.getAttributeValue("puesto");
            String sueldo             = e.getAttributeValue("sueldo");
            boolean asignado          = e.getAttributeValue("asignado").equals("true");
            String descripcionLaboral = e.getChildText("descripcionLaboral");
            HorarioSemanal horario    = new HorarioSemanal(e.getChildText("horario"));

            AdministracionInterna.agregarEmpleado(nombre, apellido, cedula, sexo, estadoCivil, fechaNacimiento, cargo, puesto, descripcionLaboral, horario, sueldo, asignado);
        }
    }

    private static void cargarRestaurants() {
        Document doc = obtenerArchivo (fileRestaurants, "los restaurantes");

        List restaurants = doc.getRootElement().getChildren("restaurant");
        Iterator i = restaurants.iterator();

        while (i.hasNext())
        {
            Element e = (Element) i.next();
            String ID        = e.getAttributeValue("id");
            String nombre    = e.getAttributeValue("nombre");
            String ubicacion = e.getAttributeValue("ubicacion");
            String elHorario = e.getAttributeValue("horario");
            Horario horario  = new Horario(elHorario);
            int superficie   = Integer.valueOf((e.getAttributeValue("superficie")));
            int capacidad    = Integer.valueOf((e.getAttributeValue("capacidad")));

            Restaurant restaurant = new Restaurant(ID, nombre, ubicacion, horario, superficie, capacidad);

            List empleados = e.getChildren("empleado");
            Iterator j = empleados.iterator();

            while (j.hasNext())
            {
                Element f = (Element) j.next();
                String cedula = f.getText();
                Empleado empleado = AdministracionInterna.empleados.buscar(cedula);
                restaurant.agregarEmpleado(empleado);
            }

            AdministracionInterna.agregarRestaurant(restaurant);
        }
    }

    private static void cargarHabitaciones() {
        Document doc = obtenerArchivo (fileHabitaciones, "las habitaciones");

        Element lista = doc.getRootElement();
        List habitaciones = lista.getChildren("habitacion");
        Iterator i = habitaciones.iterator();

        while (i.hasNext())
        {
            Element e = (Element) i.next();
            String ID      = e.getAttributeValue("id");
            String tipo    = e.getAttributeValue("tipo");
            String estado  = e.getAttributeValue("estado");
            int superficie = Integer.valueOf(e.getAttributeValue("superficie"));
            int capacidad  = Integer.valueOf(e.getAttributeValue("capacidad"));
            int reservas   = Integer.valueOf(e.getAttributeValue("reservas"));
            List fechas    = cargarFechasReservadas(ID);

            AdministracionInterna.agregarHabitacion(ID, tipo, estado, superficie, capacidad, reservas, fechas);
        }
    }

    private static void cargarClientes() {
        Document doc = obtenerArchivo (fileClientes, "los clientes");
        Element lista = doc.getRootElement();
        List empleados = lista.getChildren("cliente");
        Iterator i = empleados.iterator();

        while (i.hasNext())
        {
            Element e = (Element) i.next();
            String nombre           = e.getAttributeValue("nombre");
            String apellido         = e.getAttributeValue("apellido");
            String cedula           = e.getAttributeValue("cedula");
            char sexo               = e.getAttributeValue("sexo").charAt(0);
            char estadoCivil        = e.getAttributeValue("estadoCivil").charAt(0);
            String fechaNacimiento  = e.getAttributeValue("fechaNacimiento");
            String usuario          = e.getAttributeValue("usuario");
            String clave            = e.getAttributeValue("clave");
            String nacionalidad     = e.getAttributeValue("nacionalidad");

            Cliente cliente    = new Cliente(nombre, apellido, cedula, sexo, estadoCivil, fechaNacimiento, usuario, clave, nacionalidad);
            List <Reservacion> reservaciones = cargarReservaciones(cliente);

            if (reservaciones == null)
                reservaciones = new LinkedList();

            Iterator j = reservaciones.iterator();
            while (j.hasNext())
                cliente.agregarReservacion((Reservacion) j.next());

            Operaciones.reservaciones.agregar(reservaciones);
            AdministracionInterna.agregarCliente(cliente);
        }
    }

    private static List cargarFechasReservadas (String idHabitacion) {
        String msjError = "las fechas reservacas de la habitacion " + idHabitacion;
        String archivo  = dirFechas + idHabitacion + ".xml";
        Document doc = obtenerArchivo (archivo, msjError);

        List fechas = new LinkedList();
        List cargaFechas = doc.getRootElement().getChildren("fecha");
        Iterator i = cargaFechas.iterator();

        while (i.hasNext())
        {
            Element e = (Element) i.next();
            String laFecha = e.getText();
            Fecha fecha = new Fecha(laFecha);
            fechas.add(fecha);
        }

        return fechas;
    }

    private static List cargarReservaciones (Cliente cliente) {
        String msjError = "las reservaciones del cliente " + cliente.getCedula();
        String archivo  = dirReservas + cliente.getCedula() + ".xml";

        File file = new File(archivo);

        if (!file.exists())
            return null;

        Document doc = obtenerArchivo (archivo, msjError);

        Element lista = doc.getRootElement();
        List cargaReservaciones = lista.getChildren("reservacion");
        List reservaciones = new LinkedList();
        Iterator i = cargaReservaciones.iterator();

        while (i.hasNext())
        {
            Element e = (Element) i.next();

            String ID             = e.getAttributeValue("id");
            String idHabitacion   = e.getAttributeValue("habitacion");
            String fechaInicio    = e.getAttributeValue("fechaInicio");
            String fechaFin       = e.getAttributeValue("fechaFin");
            String fechaCompra    = e.getAttributeValue("fechaCompra");
            float  subTotal       = Float.valueOf(e.getAttributeValue("sub-Total"));
            float  montoTotal     = Float.valueOf(e.getAttributeValue("total"));
            Habitacion habitacion = Operaciones.habitaciones.buscar(idHabitacion);
            List acompañantes     = cargarAcompañantes (e.getChildren("acompanante"));

            Reservacion reservacion = new Reservacion (ID, cliente, habitacion, acompañantes, fechaInicio, fechaFin, fechaCompra, subTotal, montoTotal);

            reservaciones.add(reservacion);
        }

        return reservaciones;
    }

    private static List cargarAcompañantes (List cargaAcompañantes) {
        Iterator i = cargaAcompañantes.iterator();
        List acompañantes = new LinkedList();

        while (i.hasNext())
        {
            Element e = (Element) i.next();
            String nombre           = e.getAttributeValue("nombre");
            String apellido         = e.getAttributeValue("apellido");
            String cedula           = e.getAttributeValue("cedula");
            char sexo               = e.getAttributeValue("sexo").charAt(0);
            String fechaNacimiento  = e.getAttributeValue("fechaNacimiento");

            Persona acompañante = new Persona(nombre, apellido, cedula, sexo, fechaNacimiento);
            acompañantes.add(acompañante);
        }

        return acompañantes;
    }

    private static Document obtenerArchivo (String archivo, String textoError) {
        SAXBuilder builder = new SAXBuilder(false);
        Document doc = null;

        try
        {
            doc = (Document) builder.build(archivo);
        }
        catch (Exception e)
        {
            String error = errorCargando + textoError + "\n" + e.getMessage();
            JOptionPane.showMessageDialog(null, error);
            System.exit(666);
        }

        if (doc == null)
            System.exit(666);

        return doc;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Escritura">
    private static void guardarCargos() {
        Element root = new Element("Cargos");

        Cargo cargos[] = AdministracionInterna.cargos.array();
        int i, l = cargos.length;

        for (i = 0; i < l; i++)
        {
            Element cargo = new Element ("cargo");
            cargo.setAttribute ("nombre",     cargos[i].getNombre());
            cargo.setAttribute ("sueldoBase", String.valueOf(cargos[i].getSueldoBase()));
            root.addContent(cargo);
        }

        Document doc = new Document(root);

        try
        {
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setIndent("\t"));
            FileWriter writer = new FileWriter(fileCargos);
            outputter.output(doc, writer);
            writer.close();
        }
        catch (Exception e)
        {
            System.err.println(e.getMessage());
        }
    }

    private static void guardarEmpleados() {
        Element root = new Element("Empleados");

        Empleado empleados[] = AdministracionInterna.empleados.array();
        int i, l = empleados.length;

        for (i = 0; i < l; i++)
        {
            Element empleado = new Element ("empleado");
            empleado.setAttribute ("nombre",          empleados[i].getNombre());
            empleado.setAttribute ("apellido",        empleados[i].getApellido());
            empleado.setAttribute ("cedula",          empleados[i].getCedula());
            empleado.setAttribute ("sexo",            Character.toString(empleados[i].getSexo()));
            empleado.setAttribute ("estadoCivil",     Character.toString(empleados[i].getSexo()));
            empleado.setAttribute ("fechaNacimiento", empleados[i].getFechaNacimiento().toString());
            empleado.setAttribute ("cargo",           empleados[i].getCargo().getNombre());
            empleado.setAttribute ("puesto",          empleados[i].getPuesto());
            empleado.setAttribute ("sueldo",          String.valueOf(empleados[i].getSueldo()));
            empleado.setAttribute ("asignado",        String.valueOf(empleados[i].isAsignado()));

            Element descripcionLaboral = new Element("descripcionLaboral");
            descripcionLaboral.setText(empleados[i].getDescripcionLaboral());
            empleado.addContent(descripcionLaboral);

            Element horario = new Element("horario");
            horario.setText(empleados[i].getHorario().toString());
            empleado.addContent(horario);

            root.addContent(empleado);
        }

        Document doc = new Document(root);

        try
        {
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setIndent("\t"));
            FileWriter writer = new FileWriter(fileEmpleados);
            outputter.output(doc, writer);
            writer.close();
        }
        catch (Exception e)
        {
            System.err.println(e.getMessage());
        }
    }

    private static void guardarRestaurants() {
        Element root = new Element("Restaurants");

        Restaurant[] restaurants = AdministracionInterna.restaurants.array();
        int i, l = restaurants.length;

        for (i = 0; i < l; i++)
        {
            Element restaurant = new Element ("restaurant");
            restaurant.setAttribute ("id",         restaurants[i].getID());
            restaurant.setAttribute ("nombre",     restaurants[i].getNombre());
            restaurant.setAttribute ("ubicacion",  restaurants[i].getUbicacion());
            restaurant.setAttribute ("horario",    restaurants[i].getHorario().toString());
            restaurant.setAttribute ("superficie", String.valueOf(restaurants[i].getSuperficie()));
            restaurant.setAttribute ("capacidad",  String.valueOf(restaurants[i].getCapacidad()));

            Empleado[] listaEmpleados = restaurants[i].getEmpleados();
            int j, m = listaEmpleados.length;

            for (j = 0; j < m; j++)
            {
                Element empleado = new Element("empleado");
                empleado.setText(listaEmpleados[j].getCedula());
                restaurant.addContent(empleado);
            }

            root.addContent(restaurant);
        }

        Document doc = new Document(root);

        try
        {
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setIndent("\t"));
            FileWriter writer = new FileWriter(fileRestaurants);
            outputter.output(doc, writer);
            writer.close();
        }
        catch (Exception e)
        {
            System.err.println(e.getMessage());
        }
    }

    private static void guardarHabitaciones() {
        Element root = new Element("Habitaciones");

        Habitacion[] habitaciones = Operaciones.habitaciones.array();
        int i, l = habitaciones.length;

        for (i = 0; i < l; i++)
        {
            Element habitacion = new Element ("habitacion");
            habitacion.setAttribute ("id",         habitaciones[i].getID());
            habitacion.setAttribute ("tipo",       habitaciones[i].getTipo());
            habitacion.setAttribute ("estado",     habitaciones[i].getEstado());
            habitacion.setAttribute ("superficie", String.valueOf(habitaciones[i].getSuperficie()));
            habitacion.setAttribute ("capacidad",  String.valueOf(habitaciones[i].getCapacidad()));
            habitacion.setAttribute ("reservas",   String.valueOf(habitaciones[i].getVecesReservada()));
            root.addContent(habitacion);
            guardarFechas (habitaciones[i]);
        }

        Document doc = new Document(root);

        try
        {
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setIndent("\t"));
            FileWriter writer = new FileWriter(fileHabitaciones);
            outputter.output(doc, writer);
            writer.close();
        }
        catch (Exception e)
        {
            System.err.println(e.getMessage());
        }
    }

    private static void guardarClientes() {
        Element root = new Element("Clientes");

        Cliente[] clientes = Operaciones.clientes.array();
        int i, l = clientes.length;

        for (i = 0; i < l; i++)
        {
            Element cliente = new Element ("cliente");
            cliente.setAttribute ("nombre",          clientes[i].getNombre());
            cliente.setAttribute ("apellido",        clientes[i].getApellido());
            cliente.setAttribute ("cedula",          clientes[i].getCedula());
            cliente.setAttribute ("sexo",            Character.toString(clientes[i].getSexo()));
            cliente.setAttribute ("estadoCivil",     Character.toString(clientes[i].getEstadoCivil()));
            cliente.setAttribute ("fechaNacimiento", clientes[i].getFechaNacimiento().toString());
            cliente.setAttribute ("usuario",         clientes[i].getUsuario());
            cliente.setAttribute ("clave",           clientes[i].getClave());
            cliente.setAttribute ("nacionalidad",    clientes[i].getNacionalidad());
            guardarReservaciones(clientes[i]);
            root.addContent(cliente);
        }

        Document doc = new Document(root);

        try
        {
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setIndent("\t"));
            FileWriter writer = new FileWriter(fileClientes);
            outputter.output(doc, writer);
            writer.close();
        }
        catch (Exception e)
        {
            System.err.println(e.getMessage());
        }
    }

    private static void guardarFechas(Habitacion habitacion) {
        String archivo = dirFechas + habitacion.getID() + ".xml";

        Element root = new Element("Fechas");

        Fecha fechas[] = habitacion.getFechasReservadas();
        int i, l = fechas.length;

        for (i = 0; i < l; i++)
        {
            Element fecha = new Element ("Fecha");
            fecha.setText (fechas[i].toString());
            root.addContent(fecha);
        }

        Document doc = new Document(root);

        try
        {
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setIndent("\t"));
            FileWriter writer = new FileWriter(archivo);
            outputter.output(doc, writer);
            writer.close();
        }
        catch (Exception e)
        {
            System.err.println(e.getMessage());
        }
    }

    private static void guardarReservaciones(Cliente cliente) {
        Element root = new Element("Reservaciones");

        Reservacion[] reservaciones = cliente.getReservaciones();
        int i, l = reservaciones.length;

        for (i = 0; i < l; i++)
        {
            Element reservacion = new Element ("reservacion");
            reservacion.setAttribute ("id",          reservaciones[i].getID());
            reservacion.setAttribute ("habitacion",  reservaciones[i].getHabitacion().getID());
            reservacion.setAttribute ("fechaInicio", reservaciones[i].getFechaInicio().toString());
            reservacion.setAttribute ("fechaFin",    reservaciones[i].getFechaFin().toString());
            reservacion.setAttribute ("fechaCompra", reservaciones[i].getFechaCompra().toString());
            reservacion.setAttribute ("sub-Total",   String.valueOf(reservaciones[i].getPrecioSubTotal()));
            reservacion.setAttribute ("total",       String.valueOf(reservaciones[i].getPrecioTotal()));

            Persona[] listaAcompañantes = reservaciones[i].getAcompañantes();
            int j, m = listaAcompañantes.length;

                for (j = 0; j < m; j++)
                {
                    Element acompañante = new Element("acompañante");
                    acompañante.setAttribute("nombre",          listaAcompañantes[j].getNombre());
                    acompañante.setAttribute("apellido",        listaAcompañantes[j].getApellido());
                    acompañante.setAttribute("cedula",          listaAcompañantes[j].getCedula());
                    acompañante.setAttribute("sexo",            Character.toString(listaAcompañantes[j].getSexo()));
                    acompañante.setAttribute("fechaNacimiento", listaAcompañantes[j].getFechaNacimiento().toString());
                    reservacion.addContent(acompañante);
                }

            root.addContent(reservacion);
        }

        Document doc = new Document(root);

        try
        {
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setIndent("\t"));
            FileWriter writer = new FileWriter(dirReservas + cliente.getCedula() + ".xml");
            outputter.output(doc, writer);
            writer.close();
        }
        catch (Exception e)
        {
            System.err.println(e.getMessage());
        }
    }
    // </editor-fold>
}
